﻿using System;


namespace DailyFx.IndicatorExtension
{

	public class MACD : Index
	{
		private readonly int cPeriod	= 9; //  typically, 9 days; allows to modify ?? .
		private readonly int cFastStep	= 12;
		private readonly int cSlowStep	= 26;


        /// <summary>
		/// C'tor 
		/// </summary>
		public MACD ( int n ) : base ( 3, n )
		{

            this.MACDimpl   = new HyperVector (n, "MACD"	, Layout.SLAVE, Stylus.LINE, 0);
            this.Signal     = new HyperVector (n, "Signal"  , Layout.SLAVE, Stylus.LINE, 0);
            this.Histogram  = new HyperVector (n, "Histogram", Layout.SLAVE, Stylus.HISTOGRAM, 0);

		}

		/// <summary>
		/// 
		/// </summary>
        public override void Cook ( BarSeries series )
		{

			// todo: caches to indicator manager .
			//
            EMA fast = new EMA ( cFastStep, Length);
			EMA slow = new EMA ( cSlowStep, Length);
            fast.Cook( series);
            slow.Cook( series);


			decimal sum = 0.0m;
            decimal w = 2 / (cPeriod + 1);

			decimal m = 0.0m;
			decimal s = 0.0m;
			decimal h = 0.0m;

			for (int i = 0; i < Length; i++)   
            {
				m = fast[i, 0] - slow[i, 0];
                
				//
                if (i < cPeriod) {
					 sum += series[i ].LastPx;
					s = sum / (i + 1) ;
				}
				else {
					s = s + (series[i].LastPx - s) * w;
				}

				h = m - s;

                MACDimpl[ i]	= m;
                Signal[i]		= s;
                Histogram[i]	= h;
            }
		}


        public override string Family
        {
            get { return "Moving Average Convergence-Divergence"; }
        }

        public override string Label
        {
            get { return "MACD"; }
        }

		
        public HyperVector MACDimpl 
        {
            get  {
				return _children[0]; 
            }
            private set {
				_children[0] = value;
            }
        }

        public HyperVector Signal
        {
            get { 
                return _children[1]; 
            }
            private set {
                _children[1] = value;
            }
        }

		public HyperVector Histogram
        {
            get {
				return _children[2]; 
            }
            private set {
				_children[2] = value;
            }
        }


	} // ks MACD

} 
